import { rulesMap } from '@/rules/rules_map.js';
import { $demoi18n } from '@/utils/lang';

/**
 *
 * @export
 * @param {object} checkValues 需要校验的值 eg:{ editGroupName: this.editGroupData.name }
 * @param {object} rules 校验规则 eg: { editGroupName: { type: "string", required: true, max: 50, message: 'xxx' } }
 */

function transform(value) {
  return typeof value === 'string' ? value.trim() : value;
}

export function genMaxRule({ max = 80, label = '', trigger = 'blur' } = {}) {
  return [
    {
      max,
      message: $demoi18n('panel.rules.maxRule', [label, max]),
      trigger: trigger,
      transform,
    },
  ];
}

export function genMinRule({ min = 0, label = '', trigger = 'blur' } = {}) {
  return [
    {
      min,
      message: $demoi18n('_common_.minLength', [label, min]),
      trigger: trigger,
      transform,
    },
  ];
}

export function genRequireRule({ required = true, label = '', type = 'string', trigger = 'blur' } = {}) {
  return [
    {
      required: required,
      message: $demoi18n('panel.rules.required', [label]),
      trigger: trigger,
      type,
      transform: value => {
        let _value = value;
        if (type === 'string' && typeof _value !== 'string') {
          _value = `${_value}`;
        }
        return transform(_value);
      },
    },
  ];
}

// 正常的字符串校验 7个特殊字符 <>&"'()
export const generateRules = ({
  required = true,
  max = 80,
  specilChar = true,
  label = '',
  trigger = ['blur', 'change'],
  reg = /[<>&"]/,
} = {}) => [
  ...genRequireRule({
    required,
    label,
    trigger,
  }),
  ...genMaxRule({
    max,
    trigger,
    label,
  }),
  specilChar ?
    {
      validator(rule, value, callback, source, options) {
        if (new RegExp(reg).test(value)) {
          return callback(new Error($demoi18n('panel.rules.specelChar', [label])));
        }
        return callback();
      },
      trigger: trigger,
    } :
    null,
].filter(el => Boolean(el));

// 例外的字符串校验 5个特殊字符 <>&"
export const generateExceptionRules = ({
  required = true,
  max = 80,
  specilChar = true,
  label = '',
  trigger = ['blur', 'change'],
} = {}) => [
  ...genRequireRule({
    required,
    label,
    trigger,
  }),
  ...genMaxRule({
    max,
    label,
    trigger,
  }),
  specilChar ?
    {
      validator(rule, value, callback, source, options) {
        if (/[<>&"]/.test(value)) {
          return callback(new Error($demoi18n('panel.rules.specelChar', [label])));
        }
        return callback();
      },
      trigger: trigger,
    } :
    null,
].filter(el => Boolean(el));

export const generateSearchRule = ({ max = 80, label = '', trigger = 'blur' } = {}) => [
  ...genMaxRule({
    max,
    label,
    trigger,
  }),
  {
    validator(rule, value, callback, source, options) {
      if (/[<>]/.test(value)) {
        return callback(new Error($demoi18n('panel.rules.specelChar', [label])));
      }
      return callback();
    },
    trigger: trigger,
  },
];

export const generateUrlRule = ({ required = false, label = '', max = 1000, trigger = 'blur' } = {}) => [
  ...genRequireRule({
    required,
    label,
    trigger,
  }),
  ...genMaxRule({
    max,
    trigger,
    label,
  }),
  {
    validator(rule, value, callback, source, options) {
      const regex = /^(\.\/|\/|\/\/|http:\/\/|ftp:\/\/|https:\/\/)([\w\-:[\]]+)([\w\-.,@?^=%&amp;:/~+#{}[\]]*)?$/;

      if ( Boolean(value) && !regex.test(value) ) {
        return callback(new Error($demoi18n('panel.rules.urlFomat', [label])));
      }
      return callback();
    },
    trigger: trigger,
    transform,
  },
];

export const genIntegerRule = ({ required = true, min, max, label = '', type = 'number', trigger = 'change' } = {}) => [
  {
    ...genRequireRule({
      required,
      label,
      trigger,
    }),
    type,
    validator(rule, value, callback, source, options) {
      const parseVal = parseInt(value);
      if (typeof parseVal !== 'number') {
        return callback(new Error($demoi18n('panel.rules.plsInputNum', [label])));
      }

      if (parseVal < min || parseVal > max || !/^[0-9]*$/.test(parseVal)) {
        return callback(new Error($demoi18n('panel.rules.numLimit', [min, max])));
      }

      return callback();
    },
    trigger: trigger,
  },
];

// 根据rules_map.js配置生成规则
export const genRulesByKey = (key, label = '') => {
  let rules = [];
  const conf = rulesMap[key];
  if (conf) {
    if (conf.type === 'string') {
      if (!/color/i.test(key)) {
        rules = generateRules({
          type: 'string',
          required: conf.required,
          max: conf.max,
          label: label || conf.label,
        });
      }
    } else if (conf.type === 'number') {
      rules = genRequireRule({
        type: 'number',
        required: conf.required,
        label: label || conf.label,
      });
    } else if (conf.type === 'enum') {
      if (conf.required) {
        rules.push({
          required: true,
          message: $demoi18n('panel.rules.required', [conf.label]),
          trigger: 'change',
          transform,
        });
      }

      rules.push({
        type: 'enum',
        enum: conf.enumValues.map(n => n.value),
        message: $demoi18n('panel.rules.notInEnumVals', [conf.label]),
        trigger: 'change',
      });
    } else {}
  }
  return rules;
};

export const specialCharRule = {
  regex: /^[0-9a-zA-Z\u4e00-\u9fa5,.!;()_%-\s\uff0c\u3002\uff01\uff1b\uff08\uff09\u2014\u3001]*$/,
  message: $demoi18n('message.genNoDataPromptRules'),
};

// 无数据提示校验 只允许输入数字，中英文的逗号、句号、感叹号、顿号、分号、小括号、空格、下划线、中划线、百分号
export const genNoDataPromptRules = ({
  max = 80,
  required = true,
  specilChar = true,
  label = '',
  trigger = ['blur', 'change'],
} = {}) => [
  ...genRequireRule({
    required,
    label,
    trigger,
  }),
  ...genMaxRule({
    max,
    label,
    trigger,
  }),
  specilChar ?
    {
      validator(rule, value, callback, source, options) {
        if (specialCharRule.regex.test(value)) {
          return callback();
        }
        return callback(new Error(specialCharRule.message));
      },
      trigger: trigger,
    } :
    null,
].filter(el => Boolean(el));

export const getCssPathRules = () => {
  const rules = generateRules({
    label: $demoi18n('rules.cssPath'),
    required: true,
    specilChar: true,
    max: 1000,
    reg: /[<&"]/,
  });
  return rules;
};
